<script setup>
import { ref, computed, onMounted, nextTick, onUnmounted } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import { md } from '@/utils/markdown'
import useSafeAreaInsets from '@/composables/useSafeAreaInsets'
import 'highlight.js/styles/atom-one-dark.css'
import { useStore } from 'vuex'
import useLocale from '@/composables/useLocale'
import StyledImage from '../StyledImage.vue'

const store = useStore()
const safeAreaInsets = useSafeAreaInsets()
const scrollTop = ref(0)
const { t } = useLocale()

const hasNextPage = computed(() => store.state.chat.hasNextPage)
const currentRoomId = computed(() => store.state.chat.currentRoomId)
const isGenerating = computed(() => store.state.chat.isGenerating)
const generatingMessage = computed(() => store.state.chat.generatingMessage)
const isGeneratingImage = computed(() => store.state.chat.isGeneratingImage)
const history = computed(() => store.state.chat.history)
let currentPage = 0

const isFetchingNextPage = ref(false)
const handleScrollToTop = useDebounceFn(async () => {
    if (!hasNextPage.value || isFetchingNextPage.value) {
        return
    }
    isFetchingNextPage.value = true
    currentPage++
    await store.dispatch('chat/fetchHistoryNextPage', {
        roomId: currentRoomId.value,
        page: currentPage,
    })
    isFetchingNextPage.value = false
})

// #ifdef WEB
function handleOnWheel(e) {
    if (e.deltaY === 0) {
        return
    }
    const scrollTopVal = scrollTop.value - e.deltaY
    const query = uni.createSelectorQuery()
    query.select('.chat-scroll-view').boundingClientRect()
    query.select('.scroll-view-content').boundingClientRect()
    query.exec((res) => {
        const scrollHeight = res[1].height - res[0].height + 12
        scrollTop.value =
            scrollTopVal < 0
                ? 0
                : scrollTopVal > scrollHeight
                  ? scrollHeight
                  : scrollTopVal
    })
    e.preventDefault()
}
onMounted(async () => {
    await nextTick()
    document
        .querySelector('.chat-scroll-view .uni-scroll-view')
        ?.addEventListener('wheel', handleOnWheel, { passive: false })
})
onUnmounted(() => {
    document
        .querySelector('.chat-scroll-view .uni-scroll-view')
        ?.removeEventListener('wheel', handleOnWheel, { passive: false })
})
// #endif

function handlePreviewImage(files, current) {
    const urls = files.map((file) => file.fileUrl)
    uni.previewImage({
        urls,
        current,
    })
}
</script>

<template>
    <scroll-view
        class="chat-scroll-view h-full [transform:rotateX(180deg)]"
        scroll-y
        :scroll-top="scrollTop"
        upper-threshold="300"
        @scrolltolower="handleScrollToTop"
    >
        <view
            class="scroll-view-content flex min-h-full flex-col justify-end gap-3 px-3"
            data-test="Hello world"
            :style="{
                scrollPaddingTop: `${(safeAreaInsets?.bottom ?? 0) + 12}px`,
            }"
        >
            <view
                v-if="isGenerating || isGeneratingImage"
                class="[transform:rotateX(180deg)]"
            >
                <view class="flex items-center">
                    <view class="size-5 rounded-full bg-purple-600"></view>
                    <view class="ml-2 text-xs">CHATGPT</view>
                </view>
                <view class="mt-1 pl-7">
                    <view
                        v-if="isGeneratingImage"
                        class="text-sm text-zinc-500"
                    >
                        {{ t('imageGenerating') }}
                    </view>
                    <view
                        v-else
                        class="break-word"
                        v-html="md.render(`${generatingMessage}●`)"
                    ></view>
                </view>
            </view>

            <view
                v-for="(record, idx) in history"
                :id="idx"
                :key="idx"
                class="flex flex-col [transform:rotateX(180deg)]"
            >
                <view class="flex items-center">
                    <view
                        v-if="record.role === 'user'"
                        class="size-5 rounded-full bg-orange-700"
                    ></view>

                    <view
                        v-else
                        class="size-5 rounded-full bg-purple-600"
                    ></view>
                    <view class="ml-2 text-xs">
                        {{ record.role === 'user' ? 'YOU' : 'CHATGPT' }}
                    </view>
                </view>
                <view class="mt-1 pl-7">
                    <view class="flex gap-2 overflow-x-auto">
                        <StyledImage
                            v-for="(file, fIdx) in record.files?.filter(
                                (f) => f.type === 0,
                            )"
                            :key="fIdx"
                            :src="file.fileUrl"
                            @click="handlePreviewImage(record.files, fIdx)"
                        />
                    </view>
                    <view
                        v-if="
                            record.files?.filter((f) => f.type === 1).length > 0
                        "
                        class="flex flex-col gap-2 py-2"
                    >
                        <view
                            v-for="(file, fIdx) in record.files?.filter(
                                (f) => f.type === 1,
                            )"
                            :key="fIdx"
                            class="flex items-center gap-2"
                        >
                            <uni-icons
                                font-family="heroicons-outline"
                                :size="22"
                            >
                                {{ '\ue995' }}
                            </uni-icons>
                            <text>{{ file.fileName }}</text>
                        </view>
                    </view>
                    <view
                        class="rich-text-content select-text text-base"
                        v-html="md.render(record.message ?? '')"
                    />
                </view>
            </view>
            <view
                v-if="isFetchingNextPage"
                class="flex justify-center py-1 text-sm text-zinc-600 [transform:rotateX(180deg)]"
            >
                {{ t('loading') }}
            </view>
        </view>
    </scroll-view>
</template>

<style lang="scss" scoped>
.rich-text-content {
    p {
        line-height: 1.75rem;
    }
}
</style>
